package com.learning.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.learning.dto.AnswerDTO;
import com.learning.dto.GradeDTO;
import com.learning.entity.Answer;
import com.learning.entity.AnswerByStudent;
import com.learning.entity.AnswerPaper;
import com.learning.entity.ExamPaper;
import com.learning.entity.ExamPaperQuestion;
import com.learning.entity.Knowledge;
import com.learning.entity.Question;
import com.learning.enums.QuestionType;
import com.learning.mapper.AnswerByStudentMapper;
import com.learning.mapper.AnswerMapper;
import com.learning.mapper.AnswerPaperMapper;
import com.learning.mapper.ExamPaperMapper;
import com.learning.mapper.ExamPaperQuestionMapper;
import com.learning.mapper.KnowledgeMapper;
import com.learning.mapper.QuestionMapper;
import com.learning.service.IAnswerPaperService;
import com.learning.vo.AnswerPaperFinishedVO;
import com.learning.vo.AnswerPaperVO;
import com.learning.vo.ExamResultVO;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

@Service
public class AnswerPaperServiceImpl implements IAnswerPaperService {

	@Resource
	private ExamPaperMapper examPaperMapper;
	@Resource
	private ExamPaperQuestionMapper examPaperQuestionMapper;
	@Resource
	private QuestionMapper questionMapper;
	@Resource
	private AnswerPaperMapper answerPaperMapper;
	@Resource
	private AnswerByStudentMapper answerByStudentMapper;
	@Resource
	private AnswerMapper answerMapper;
	@Resource
	private KnowledgeMapper knowledgeMapper;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public AnswerPaperVO getAnswerPaper(Long studentId) {

		// 随机获取一张试卷
		List<ExamPaper> examPapers = examPaperMapper.selectAll();
		int size = examPapers.size();
		Assert.isTrue(size > 0, "发卷失败：试卷库为空");

		ExamPaper examPaper = examPapers.get((int) (Math.random() * size));
		List<ExamPaperQuestion> examPaperQuestions = examPaperQuestionMapper.selectByExamPaperId(examPaper.getId());

		// 入库
		AnswerPaper answerPaper = new AnswerPaper();
		answerPaper.setExamPaperId(examPaper.getId());
		answerPaper.setStudentId(studentId);
		answerPaper.setScore(String.valueOf(examPaper.getTotalScore()));
		answerPaper.setGrade("0");
		answerPaper.setChecked(false);
		answerPaper.setCreateTime(LocalDateTime.now());
		answerPaperMapper.insert(answerPaper);

		// 返回vo
		AnswerPaperVO answerPaperVO = new AnswerPaperVO();
		answerPaperVO.setAnswerPaperId(answerPaper.getId());
		answerPaperVO.setTotalScore(Integer.valueOf(examPaper.getTotalScore()));
		answerPaperVO.setCreateTime(answerPaper.getCreateTime());
		List<AnswerPaperVO.QuestionVO> questionList = new ArrayList<>();
		for (ExamPaperQuestion examPaperQuestion : examPaperQuestions) {
			Question question = questionMapper.queryById(examPaperQuestion.getQuestionId());

			AnswerPaperVO.QuestionVO questionVO = new AnswerPaperVO.QuestionVO();
			questionVO.setQuestionId(examPaperQuestion.getQuestionId());
			questionVO.setScore(examPaperQuestion.getQuestionScore());
			questionVO.setType(question.getType());
			questionVO.setContent(question.getQuestionContent());

			questionList.add(questionVO);
		}
		answerPaperVO.setQuestionList(questionList);
		return answerPaperVO;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String checkAnswerPaper(Long answerPaperId, List<GradeDTO> gradeList) {
		float totalGrade = 0;
		// 查询答卷
		AnswerPaper answerPaper = answerPaperMapper.selectById(answerPaperId);
		Assert.notNull(answerPaper, "判卷失败：答卷不存在");

		List<ExamPaperQuestion> examPaperQuestions = examPaperQuestionMapper.selectByExamPaperId(answerPaper.getExamPaperId());

		// 客观题自动算分
		for (ExamPaperQuestion examPaperQuestion : examPaperQuestions) {
			// 查询题目和答案
			Question question = questionMapper.queryById(examPaperQuestion.getQuestionId());
			Assert.notNull(answerPaper, "判卷失败：题目(id=" + examPaperQuestion.getQuestionId() + ")不存在");
			if (!question.getType().equalsValue(QuestionType.SUBJECTIVE.getValue())) {
				Answer answer = answerMapper.selectOne(new QueryWrapper<Answer>().eq("question_id", examPaperQuestion.getQuestionId()));
				Assert.notNull(answer, "判卷失败：题目(id=" + examPaperQuestion.getQuestionId() + ")的答案不存在");

				AnswerByStudent answerByStudent = answerByStudentMapper.selectOne(new QueryWrapper<AnswerByStudent>().eq("answer_paper_id", answerPaperId).eq("question_id", examPaperQuestion.getQuestionId()));
				Assert.notNull(answerByStudent, "判卷失败：题目(id=" + examPaperQuestion.getQuestionId() + ")的学生作答不存在");

				String answerContent = answer.getAnswerContent();
				if(question.getType().equalsValue(QuestionType.CHOICE.getValue())) {
					// 选择题
					answerContent = answerContent.substring(0, 1);
				}
				float grade;
				if(answerByStudent.getAnswer().equals(answerContent)) {
					// 回答正确
					grade = examPaperQuestion.getQuestionScore();
					totalGrade += grade;
				}else {
					// 回答错误
					grade = 0;
					answerByStudent.setWrong(true);
				}
				answerByStudent.setGrade(String.valueOf(grade));
				answerByStudentMapper.updateById(answerByStudent);
			}
		}
		// 主观题
		for (GradeDTO gradeDTO : gradeList) {
			AnswerByStudent answerByStudent = answerByStudentMapper.selectOne(new QueryWrapper<AnswerByStudent>().eq("answer_paper_id", answerPaperId).eq("question_id", gradeDTO.getQuestionId()));
			Assert.notNull(answerByStudent, "判卷失败：题目(id=" + gradeDTO.getQuestionId() + ")的学生作答不存在");

			ExamPaperQuestion examPaperQuestion = examPaperQuestionMapper.queryByExamPaperIdAndQuestionId(answerPaper.getExamPaperId(), Long.valueOf(gradeDTO.getQuestionId()));
			Assert.notNull(examPaperQuestion, "判卷失败：试卷(id=" + answerPaper.getExamPaperId() + ")题目(id=" + gradeDTO.getQuestionId() + ")的题目不存在");

			answerByStudent.setGrade(gradeDTO.getGrade());
			if (!gradeDTO.getGrade().equals(String.valueOf(examPaperQuestion.getQuestionScore()))) {
				answerByStudent.setWrong(true);
			}
			answerByStudentMapper.updateById(answerByStudent);
			totalGrade += Float.parseFloat(gradeDTO.getGrade());
		}

		// 更新答卷
		answerPaper.setGrade(String.valueOf(totalGrade));
		answerPaper.setChecked(true);
		answerPaperMapper.updateById(answerPaper);

		return String.valueOf(totalGrade);
	}

	@Override
	public List<ExamResultVO> getExamResultList(Long studentId) {
		List<ExamResultVO> examResultVOs = new ArrayList<>();

		answerPaperMapper.selectList(new QueryWrapper<AnswerPaper>().eq("student_id", studentId)).forEach(answerPaper -> {
			ExamResultVO examResultVO = new ExamResultVO();
			examResultVO.setAnswerPaperId(answerPaper.getId());
			examResultVO.setScore(answerPaper.getScore());
			examResultVO.setGrade(answerPaper.getGrade());
			examResultVO.setExamTime(answerPaper.getCreateTime());
			List<String> knowledgeList = new ArrayList<>();
			List<AnswerByStudent> answerByStudents = answerByStudentMapper.selectList(new QueryWrapper<AnswerByStudent>().eq("answer_paper_id", answerPaper.getId()).eq("wrong", true));
			for (AnswerByStudent answerByStudent : answerByStudents) {
				Knowledge knowledge = knowledgeMapper.queryByQuestionId(answerByStudent.getQuestionId());
				if(knowledge != null){
					knowledgeList.add(knowledge.getKnowledgeContent());
				}
			}
			examResultVO.setKnowledgeList(knowledgeList);
			examResultVOs.add(examResultVO);
		});

		return examResultVOs;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submitAnswer(Long answerPaperId, List<AnswerDTO> gradeList) {
		for (AnswerDTO answerDTO : gradeList) {
			AnswerByStudent answerByStudent = new AnswerByStudent();
			answerByStudent.setAnswerPaperId(answerPaperId);
			answerByStudent.setQuestionId(answerDTO.getQuestionId());
			answerByStudent.setGrade("0");
			answerByStudent.setWrong(false);
			answerByStudent.setAnswer(answerDTO.getAnswer());
			answerByStudentMapper.insert(answerByStudent);
		}
	}

	@Override
	public List<AnswerPaperFinishedVO> getAnswerPapers() {
		List<AnswerPaper> answerPapers = answerPaperMapper.selectList(null);

		List<AnswerPaperFinishedVO> answerPaperFinishedVOs = new ArrayList<>();
		for (AnswerPaper answerPaper : answerPapers) {
			AnswerPaperFinishedVO answerPaperFinishedVO = new AnswerPaperFinishedVO();

			answerPaperFinishedVO.setAnswerPaperId(answerPaper.getId());
			answerPaperFinishedVO.setTotalScore(answerPaper.getScore());
			answerPaperFinishedVO.setTotalGrade(answerPaper.getGrade());
			answerPaperFinishedVO.setChecked(answerPaper.getChecked());
			answerPaperFinishedVO.setCreateTime(answerPaper.getCreateTime());
			List<AnswerPaperFinishedVO.QuestionVO> questionList = new ArrayList<>();
			List<AnswerByStudent> answerByStudents = answerByStudentMapper.selectList(new QueryWrapper<AnswerByStudent>().eq("answer_paper_id", answerPaper.getId()));
			if(answerByStudents.isEmpty()) {
				// 无答题记录则跳过展示该答卷
				continue;
			}
			boolean isPaperDeleted = false;
			for (AnswerByStudent answerByStudent : answerByStudents) {
				Question question = questionMapper.queryById(answerByStudent.getQuestionId());
				ExamPaperQuestion examPaperQuestion = examPaperQuestionMapper.queryByExamPaperIdAndQuestionId(answerPaper.getExamPaperId(), answerByStudent.getQuestionId());
				if(examPaperQuestion == null) {
					isPaperDeleted = true;
					break;
				}
				AnswerPaperFinishedVO.QuestionVO questionVO = new AnswerPaperFinishedVO.QuestionVO();
				questionVO.setQuestionId(answerByStudent.getQuestionId());
				questionVO.setContent(question.getQuestionContent());
				questionVO.setAnswer(answerByStudent.getAnswer());
				questionVO.setScore(String.valueOf(examPaperQuestion.getQuestionScore()));
				questionVO.setGrade(answerByStudent.getGrade());
				questionVO.setType(question.getType());
				questionList.add(questionVO);
			}
			if(isPaperDeleted) {
				// 试卷已删除则跳过展示该答卷
				continue;
			}
			answerPaperFinishedVO.setQuestionList(questionList);

			answerPaperFinishedVOs.add(answerPaperFinishedVO);
		}
		return answerPaperFinishedVOs;
	}
}
